import java.awt.Color;
import java.awt.Point;
import java.awt.image.BufferedImage;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Random;
import java.util.Vector;

import javax.imageio.ImageIO;
//draw map image and write to the FMap.txt and print selected point

public class CopyOfMultipleWalks {
	static ImageProcessing imp = new ImageProcessing(3);
	static BufferedImage image;
	static RandomWalkSquare[] walks;
	static int[] randomIndex = new int[1000];
	static String path = "C:/Users/accufind/Desktop/Files/";
	
	public CopyOfMultipleWalks(){}
	//this main method contains functions including writeCSV(), generateLocations(),
	public static void main(String[] args) throws Exception{
		
		Color colorToFind = new Color(254,0,0);	
		Vector<Point> pixels = imp.pixelSearch(colorToFind,imp.readImage());	
		int[][] maps = imp.convertToMap();
		int[][] FMap = new int[maps.length][maps[0].length];
		Random rand = new Random();
		int numPeople = rand.nextInt(1000);
		System.out.println(numPeople);
		walks = new RandomWalkSquare[numPeople];
		int numSteps;
		
		
		writeCSV(maps);
		generateLocations(maps);
		
		/*construct multiple objects, with walker(start point,squaresize,objectindex) and walk(squaresize,numSteps,stepsize)
		 * and finally the paths of all the objects*/
		Point[] points = new Point[numPeople];	
		for(int i=0;i<numPeople;i++){
			points[i] = generateStartPoint(pixels);
		}
		
		for(int i=0;i<numPeople;i++){
			numSteps = rand.nextInt(10050)+750;//may change, 750-10800, 15min-3hour
			System.out.println("Object "+(i+1)+" : "+numSteps);
			walks[i]= new RandomWalkSquare(10,numSteps,25);
			//each walk has the same squaresize and stepsize, may change to random
		}
		
		Person[] walkers = new Person[numPeople];
		for(int i=0;i<numPeople;i++){
			walkers[i] = new Person(points[i].x,points[i].y,10,i);
		}
	
		File file = new File( path +"All"+".txt");  
    	FileWriter writer = new FileWriter(file);
    		
		Point[][] paths = new Point[numPeople][150]; 		
		for(int i=0;i<numPeople;i++){
			int objectIndex = generateIndex()+1;
			paths[i]=walks[i].walkRandomly(objectIndex,writer,walkers[i],maps);
			//pass the writer to write path file for each object in All.txt for one date specified in walkRandomly()
		}
		writer.flush();
		writer.close();
		
		//After we collect the paths of one day, change the name to "day x.txt"
		//when files of all dates collected, then we export all files to "All.txt"
		exportToOneFile();
		
		//write images of paths of multiple objects in one map
		//can be commented out when generating path files
		image=imp.image;
		writeImage(image,maps,paths);
		
		drawFMap(paths,FMap);
		selectPoint(FMap);
	
	
    }
	//this method is to collect all the available location points and write to locations.txt
	//It reads the csv file of one floorplan
	private static void generateLocations(int[][] maps) throws Exception{
		System.out.println("reading...");
		BufferedReader br = new BufferedReader(new FileReader(path+"3.csv"));
		String str;
		int count =0;
		String[] tokens;
		int[] x = new int[325300];
		int[] y = new int[325300];
		while((str = br.readLine())!=null){
			tokens = str.split(",");
			x[count]=Integer.parseInt(tokens[0]);
			y[count]=Integer.parseInt(tokens[1]);
			count++;
	    }
		System.out.println("finish reading.");
		br.close();
		
		//please adjust the numbers if you change the floor map, numbers are taken from one csv file
		int[][] record = new int[74][36];
		
		for(int i=0;i<325300;i++){
			int xindex = (x[i]-178)/25;//x is 178 to 1996
			int yindex = (y[i]-4)/25;//y is 4 to 885
	        System.out.println(record[xindex][yindex]++);//build record[][]
		}
		System.out.println("printing...");
		File file = new File( path +"locations"+".txt");  
    	FileWriter writer = new FileWriter(file);
		for(int i=0;i<74;i++){
			for(int j=0;j<36;j++){
				if(record[i][j]!=0) {
					//System.out.println(i*25+","+j*25);
					writer.append((178+i*25)+","+(4+j*25)+"\n");
				}
				
			}
		}
		writer.flush();
		writer.close();
		
	}
	//this method is to make sure that the random number is not repeated
	private static int generateIndex(){
		Random rand = new Random();
		int index = rand.nextInt(1000);
		while(randomIndex[index]!=0){
			index = rand.nextInt(1000);
		}
		randomIndex[index]++;
		return index;
	}
	//this method is to collect all data of each day to one file "All.txt"
	public static void exportToOneFile() throws IOException{
		File file = new File( path +"All"+".txt");  
    	FileWriter writer = new FileWriter(file);
    	BufferedReader br;
    	for(int i=0;i<31;i++){
    		System.out.println("collecting data from day "+(i+1)+".txt ...");
    		br = new BufferedReader(new FileReader(path+"day "+(i+1)+".txt"));
    		String str;
    		while((str = br.readLine())!=null){
    			writer.append(str+"\n");
		    }
    	}
    	writer.flush();
    	writer.close();
	}
	//this method is to get random startpoint through pixels
	public static Point generateStartPoint(Vector<Point> pixels){
		int size = pixels.size();
		Random generator = new Random();
		int index = generator.nextInt(size);
		return pixels.get(index);
		
	}
	//this method is to write CSV file of available points in one floor map
	public static void writeCSV(int[][] maps) throws IOException{
		File file = new File( path+"3.csv");  
        FileWriter writer = new FileWriter(file);
        for(int i=0;i<maps.length;i++){
        	for(int j=0;j<maps[0].length;j++){
        		if(maps[i][j]==1) writer.append(i+","+j+"\n");
        	}
        }
        writer.flush();
        writer.close();
	}
	//this method print out all the points which are stepped on once or more
	public static void selectPoint(int[][] FMap){
		for(int i=0;i<FMap.length;i++){
			for(int j=0;j<FMap[0].length;j++){
				if(FMap[i][j]!=0) 
					System.out.println("("+i+","+j+")"+" Frequency:"+FMap[i][j]);
			}
		}
	}
	private static void addToFMap(Point[] path, int[][] FMap){
		int size = path.length;
		for(int i= 0;i<size;i++){
			int x = path[i].x;
			int y = path[i].y;
			FMap[x][y]++;
		}	
	}
	//this method is to write frequency of each point to a file "Fmap.txt"
	public static void drawFMap(Point[][] paths, int[][] FMap) throws IOException{
		for(int i=0;i<paths.length;i++){
			addToFMap(paths[i],FMap);
		}
		File file = new File( path+"Fmap.txt");  
    	FileWriter writer = new FileWriter(file);
    	for(int i=0;i<FMap.length;i++){
			for(int j=0;j<FMap[i].length;j++){
				writer.append(FMap[i][j]+" ");
			}
			writer.append("\n");
		}
    	    writer.flush();
    	    writer.close();
	}
	//this method is to add the corridor of red color to bufferedImage
	private static BufferedImage setImage(BufferedImage image, int[][] map){
		int w = image.getWidth();
        int h = image.getHeight(); 
		BufferedImage bufferedImage = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
		Color red = new Color(254,0,0);
		int redColor = red.getRGB();
		for(int i=0;i<map.length;i++){
			for(int j=0;j<map[0].length;j++){
				if(map[i][j]==1) bufferedImage.setRGB(i, j, redColor);
			}
		}
		return bufferedImage;
	}
	//this method set path of one object in bufferedImage
	private static BufferedImage setPath(BufferedImage image,Point[] path, int pathColor){
		for(int i=0;i<path.length;i++){
			int x=path[i].x;
			int y=path[i].y;
			for(int m=0;m<10;m++){
				for(int n=0;n<10;n++){
					image.setRGB(x+m,y+n,pathColor);
				}
			}
		}
		return image;
	}
	//this method draws images of paths and map
	public static void writeImage(BufferedImage image, int[][] map, Point[][] paths) throws IOException{
		BufferedImage bufferedImage = setImage(image,map);
		Random rand = new Random();
		Color[] colors = new Color[walks.length];
		for(int i=0;i<colors.length;i++){
			colors[i] = new Color(rand.nextFloat(),rand.nextFloat(),rand.nextFloat());
		}//get random color for one object
		for(int i=0;i<colors.length;i++){
			bufferedImage = setPath(bufferedImage, paths[i],colors[i].getRGB());
		}//set path for each object
		
		//draw image from bufferedImage
		String filename = "1 walks";
		File file = new File("C:/Users/accufind/Desktop/Files/"+filename+".jpg");
		ImageIO.write(bufferedImage,"jpg",file);
		System.out.println(file.getName());
				
	}

}
